package cn.turboinfo.fuyang.api.provider.common.service.impl.kvconfig;

import cn.turboinfo.fuyang.api.domain.common.service.kvconfig.KVConfigService;
import cn.turboinfo.fuyang.api.entity.common.exception.kvconfig.KVConfigException;
import cn.turboinfo.fuyang.api.entity.common.pojo.kvconfig.KVConfig;
import cn.turboinfo.fuyang.api.entity.common.pojo.kvconfig.KVConfigCreator;
import cn.turboinfo.fuyang.api.entity.common.pojo.kvconfig.KVConfigUpdater;
import cn.turboinfo.fuyang.api.provider.common.repository.database.kvconfig.KVConfigDAO;
import cn.turboinfo.fuyang.api.provider.common.repository.database.kvconfig.KVConfigPO;
import lombok.RequiredArgsConstructor;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanCreatorHelper;
import net.sunshow.toolkit.core.qbean.helper.component.request.QBeanUpdaterHelper;
import net.sunshow.toolkit.core.qbean.helper.service.impl.AbstractQServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

@RequiredArgsConstructor
@Service
public class KVConfigServiceImpl extends AbstractQServiceImpl<KVConfig> implements KVConfigService {
    private final KVConfigDAO kvConfigDAO;

    @Override
    public Optional<KVConfig> getById(Long id) {
        return kvConfigDAO.findById(id).map(this::convertQBean);
    }

    @Override
    public KVConfig getByIdEnsure(Long id) {
        return getById(id).orElseThrow(this.getExceptionSupplier("未找到数据, id=" + id, null));
    }

    @Override
    public List<KVConfig> findByIdCollection(Collection<Long> idCollection) {
        return convertStreamQBeanToList(kvConfigDAO.findAllByIdIn(idCollection).stream());
    }

    @Override
    @Transactional
    public KVConfig save(KVConfigCreator creator) throws KVConfigException {
        KVConfigPO kvConfigPO = new KVConfigPO();

        QBeanCreatorHelper.copyCreatorField(kvConfigPO, creator);

        return convertQBean(kvConfigDAO.save(kvConfigPO));
    }

    @Override
    @Transactional
    public KVConfig update(KVConfigUpdater updater) throws KVConfigException {
        KVConfigPO kvConfigPO = getEntityWithNullCheckForUpdate(updater.getUpdateId(), kvConfigDAO);

        QBeanUpdaterHelper.copyUpdaterField(kvConfigPO, updater);

        return convertQBean(kvConfigPO);
    }

    @Override
    @Transactional
    public void deleteById(Long id) throws KVConfigException {
        KVConfigPO kvConfigPO = getEntityWithNullCheckForUpdate(id, kvConfigDAO);
        kvConfigPO.setDeletedTime(System.currentTimeMillis());
    }

    @Override
    public Optional<KVConfig> getByConfigKey(String configKey) {
        return kvConfigDAO.findByConfigKey(configKey).map(this::convertQBean);
    }

    @Override
    public KVConfig getByConfigKeyEnsure(String configKey) {
        return getByConfigKey(configKey).orElseThrow(this.getExceptionSupplier("未找到数据, configKey=" + configKey, null));
    }

    @Override
    public List<KVConfig> findByConfigKeyCollection(Collection<String> configKeyCollection) {
        return convertStreamQBeanToList(kvConfigDAO.findByConfigKeyInOrderByIdDesc(configKeyCollection).stream());
    }

    @Override
    public List<KVConfig> findByConfigGroup(String configGroup) {
        return convertStreamQBeanToList(kvConfigDAO.findByConfigGroupOrderByGroupOrderAscIdAsc(configGroup).stream());
    }

    @Override
    @Transactional
    public KVConfig getByConfigKeyOrElse(String configKey, String defaultValue) {
        return getByConfigKey(configKey).orElseGet(() -> save(KVConfigCreator.builder().withConfigKey(configKey).withConfigValue(defaultValue).build()));
    }

    @Override
    protected Supplier<? extends RuntimeException> getExceptionSupplier(String message,
                                                                        Throwable cause) {
        return () -> new KVConfigException(message, cause);
    }
}
